2025-04-27 IPSec zwischen LANCOM-Router und strongSwan auf Alpine Linux

LANCOM 1900EF

IPSec IKEv2 VPN zwischen LANCOM (LCOS) und Alpine Linux mit strongSwan.
Versionen zum Schreibzeitpunkt: LCOS 10.90.0221RU3, Alpine Version 3.21.3, strongswan-5.9.14-r0

In diesem Beispiel hier geht es um ein sogenanntes “RoadWarrior Setup” oder auch einen “Einwahl-Zugang”/RAS. (Mit Linux-Host als Client.) Es soll nicht der ganze Internetverkehr umgeleitet, sondern nur der Zugriff auf ein internes Netz geschaffen werden.

strongSwan

Es passt irgendwie zu IPSec, das nicht nur die dazugehörigen Protokolle, sondern auch die Softwarelandschaft komplex ist. So gibt es mit strongSwan eine umfangreiche “IPSec-Implementierung” für Linux, die mit mehreren Daemons und inkompatiblen Konfigurationsdateien daher kommt. Sucht man nach Beispielen, wird oft von ipsec.conf geredet und von einem ipsec-Daemon. Hey, das klingt wie die VPN-Technik die man verwenden möchte. Aber Achtung: Die Datei und dazugehörige Syntax ist seit mehreren Jahren abgekündigt/deprecated und soll mit 6.0 komplett verschwinden. Mit strongswan.conf und swanctl.conf gibt es eine neue Konfigurationssyntax und mit charon einen ipsec ersetzenden Daemon.
Anderes als ich es von OpenBSD-Projekten gewöhnt bin, wo inkompatible Konfigurationsänderungen - sehr gut erklärt - kurz und schmerzlos durchgedrückt werden, laufen bei strongSwan und den Linux-Distributionen die beiden System seit Jahren parallel. So hatte es z.B. peinlich lange gedauert, bis ich kapiert hatte, das die neue Konfig von einem anderen Daemon verarbeitet werden muss. Das Ding heiß "ipsec" verdamt. Woher kann ich wissen das man da was ganz anderes braucht. ;-)
Wie dem auch sei, diese Anleitung beschreibt nur das “moderne” Vorgehen. (Mal davon ab, dass keine Systemd Distro verwendet wird.)

Authentifizierung mit Pre-Shared Key (PSK)

Auf dem LANCOM ganz normal einen Einwahl-VPN-Zugang anlegen. Der “Fully Qualified Username” muss dem Format einer Email entsprechen und ist dabei das, was später in der swanctl.conf die local- und remote-id sein wird.

Auf Alpine:
# apk add strongswan
# vim /etc/swanctl/conf.d/lancom-buero.conf
connections {
  buero {
    version = 2
    proposals = aes256-sha256-ecp512bp
    encap = yes
    dpd_delay = 60s

    remote_addrs = vpn.example.com
    vips = 0.0.0.0

    children {
      buero {
        esp_proposals = aes256-sha256-ecp512bp
        start_action = start
        dpd_action = restart
        close_action = start
        updown = doas /usr/lib/strongswan/_updown iptables

        remote_ts = 198.51.100.0/24
        #mobike = no # bei LCOS <10.90 Systemen auskommentieren
      }
    }
    local {
      auth = psk
      id = sw@example
    }
    remote {
      auth = psk
      id = sw@example
    }
  }
}

secrets {
  ike-sw {
    id = sw@example
    secret = "Passwort"
  }
}
#eof

# chmod 600 /etc/swanctl/conf.d/lancom-buero.conf

Komplett optional, für weniger Meldungen im Syslog.
# vim /etc/strongswan.d/lancom-logging.conf
charon {
    syslog {
        identifier = charon
        daemon {
            enc = -1
            net = -1
        }
    }
}
#eof

Falls Firewall im Einsatz:
# vim /etc/doas.d/charon.conf
# IPSec deamon charon
permit nopass keepenv ipsec as root cmd /usr/lib/strongswan/_updown args iptables
#eof

VPN-Verbindung starten:
# rc-service charon start

Automatisch beim booten starten:
# rc-update add charon
“encap = yes” Ohne verarbeitet Linux eingehende, in UDP gekapselte, ESP-Pakete nicht. ¯\_(ツ)_/¯

“remote_addrs = vpn.example.com” Domain des LANCOM-Routers. Trotz AAAA-Record wird sich mit IPv4 verbunden. Grund hab ich bisher nicht weiter analysiert. Evtl. folgt dazu später ein Update.

“remote_ts = 198.51.100.0/24” Das entfernte Netzwerk, in das man will.

“vips = 0.0.0.0” Der Client erhält eine IP vom VPN-Router zugewiesen.

“secret = "Passwort"” Das Shared Secret, der Preshared Key. Wenn die Zeichenkette ein Anführungszeichen enthält, muss diese Base64 kodiert werden. (Zusammen mit einer 0s Makierung). Dazu dieser Einzeiler:
SWB64P=`mktemp` && base64 > $SWB64P && echo && echo 0s`cat $SWB64P` && rm $SWB64P
Wichtig: Nach der Passworteingabe nicht Enter drücken, sondern dreimal Strg + d. Andernfalls wird der Zeilenumbruch mitkodiert und die Authentifizierung wird scheitern. Der Einzeiler ist nur auf Busybox getestet.

Authentifizierung mit Zertifikat

Wie man eine CA erstellt und den LANCOM-Router dafür konfiguriert, habe ich in meinem OpenSSL-Spickzettel beschrieben:
openssl.txt
openssl_Beispiel.cnf
Einfach dem Beispiel "Android mit strongSwan" folgen. Der Weg ist mehr oder weniger der Gleiche.

Auf Alpine:
Mit Cert- und Key-File:
# cp ORGANIZATION_CACert.pem /etc/swanctl/x509ca/
# cp ClientXYZ-FQDN_Cert.pem /etc/swanctl/x509/
# cp ClientXYZ-FQDN_Key.pem /etc/swanctl/private/
# chmod 400 /etc/swanctl/private/ClientXYZ-FQDN_Key.pem

# vim /etc/swanctl/conf.d/lancom-buero.conf
connections {
  buero {
    version = 2
    proposals = aes256-sha256-ecp512bp
    encap = yes
    dpd_delay = 60s

    remote_addrs = vpn.example.com
    vips = 0.0.0.0

    children {
      buero {
        esp_proposals = aes256-sha256-ecp512bp
        start_action = start
        dpd_action = restart
        close_action = start
        updown = doas /usr/lib/strongswan/_updown iptables

        remote_ts = 198.51.100.0/24
        #mobike = no # bei LCOS <10.90 Systemen auskommentieren
      }
    }
    local {
      auth = pubkey
      certs = ClientXYZ-FQDN_Cert.pem
    }
    remote {
      cacerts = ORGANIZATION_CACert.pem
    }
  }
}
#eof

Mit PKCS #12 Zertifikatcontainer:
# cp ORGANIZATION_CACert.pem /etc/swanctl/x509ca/
# cp ClientXYZ-FQDN_Cert_with_Key.p12 /etc/swanctl/pkcs12/
# openssl x509 -subject -noout -in ClientXYZ-FQDN_Cert_with_Key.p12
subject=C=DE, ST=Bavaria, O=example.com, OU=Example.com Certification Authority, CN=vpn.example.com, emailAddress=camaster@example.com

# vim /etc/swanctl/conf.d/lancom-buero.conf
...
    local {
      auth = pubkey
      id = C=DE, ST=Bavaria, O=example.com, OU=Example.com Certification Authority, CN=vpn.example.com, emailAddress=camaster@example.com
    }
    remote {
      cacerts = ORGANIZATION_CACert.pem
    }
  }
}
secrets {
  pkcs12 {
    file = ClientXYZ-FQDN_Cert_with_Key.p12
    secret = "Passwort"
  }
}
#eof

# chmod 400 /etc/swanctl/conf.d/lancom-buero.conf
Der secrets-Abschnitt ist optional. Ohne wird beim Starten des Daemon nach dem Passwort der p12-Datei gefragt.

Wie üblich die Erinnerung das einzelne VPN-Verbindung von LCOS als eigene Gegenstellen betrachtet werden und evtl. in der Firewall weitere Freigaben für die Kommunikation untereinander benötigt werden.

Homepage